package com.umeox.ota.utils;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.PowerManager;
import androidx.core.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.umeox.ota.gloable.App;
import com.umeox.ota.data.local.Installation;
import com.abupdate.trace.Trace;

import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.List;

/**
 * @author fighter_lee
 * @date 2018/7/10
 */
public class DeviceUtil {

    private static final String TAG = "DeviceUtil";
    private static String eth0 = "";
    private static String wlan0 = "";
    public static final String DEFAULT_IMEI = "default-imei";
    public static final String DEFAULT_SN = "default-sn";
    public static final String DEFAULT_MAC = "default-mac";

    /**
     * @return 判断build.prop文件中fota配置是否可用
     */
    public static boolean buildConfigValid() {
        try {
            ClassLoader cl = App.sCx.getClassLoader();
            Class systemProperties = cl.loadClass("android.os.SystemProperties");
            Class[] paramTypes = new Class[1];
            paramTypes[0] = String.class;

            Method get = systemProperties.getMethod("get", paramTypes);

            String version = (String) get.invoke(systemProperties, new Object[]{"ro.fota.version"});
            String oem = (String) get.invoke(systemProperties, new Object[]{"ro.fota.oem"});
            String models = (String) get.invoke(systemProperties, new Object[]{"ro.fota.device"});
            String platform = (String) get.invoke(systemProperties, new Object[]{"ro.fota.platform"});
            String deviceType = (String) get.invoke(systemProperties, new Object[]{"ro.fota.type"});

            if (!TextUtils.isEmpty(version) &&
                    !TextUtils.isEmpty(oem) &&
                    !TextUtils.isEmpty(models) &&
                    !TextUtils.isEmpty(platform) &&
                    !TextUtils.isEmpty(deviceType)) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * mid是否合法
     *
     * @param mid
     * @return
     */
    public static boolean isValidMid(String mid) {

        if (TextUtils.isEmpty(mid) ||
                "unknown".equalsIgnoreCase(mid) ||
                "null".equalsIgnoreCase(mid) ||
                mid.length() < 4 ||
                mid.length() > 64 ||
                mid.startsWith(DEFAULT_IMEI) ||
                mid.startsWith(DEFAULT_SN) ||
                mid.startsWith(DEFAULT_MAC)) {
            return false;
        }
        return true;
    }

    /**
     * 获取 IMEI 码
     * <p>需添加权限
     * {@code <uses-permission android:name="android.permission.READ_PHONE_STATE" />}</p>
     *
     * @return IMEI 码
     */
    public static String getIMEI() {
        TelephonyManager tm =
                (TelephonyManager) App.sCx.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm != null) {
            String imei = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                if (ActivityCompat.checkSelfPermission(App.sCx, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                    Trace.d(TAG, "getIMEI() fail, Because of lack of permissions: " + Manifest.permission.READ_PHONE_STATE);
                    return "";
                }
                imei = tm.getImei();
            } else {
                imei = tm.getDeviceId();
            }
            if (isValidMid(imei)) {
                return imei;
            }
        }
        Trace.d("iport", "get IMEI failed");
        return "";
    }

    /**
     * 获取SN号
     *
     * @return SN 号
     */
    public static String getSN() {
        String sn;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            if (ActivityCompat.checkSelfPermission(App.sCx, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                Trace.d(TAG, "getIMEI() fail, Because of lack of permissions: " + Manifest.permission.READ_PHONE_STATE);
                return "";
            }
            sn = Build.getSerial();
        } else {
            sn = Build.SERIAL;
        }
        if (isValidMid(sn)) {
            return sn;
        }
        Trace.d("iport", "get SN failed");
        return "";
    }

    /**
     * 获取 Mac 地址
     *
     * @return Mac 地址，优先eth0(以太网) mac 地址、若 eth0 为空，则使用 wlan0
     */
    public static String getMAC() {
        try {
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if ("eth0".equalsIgnoreCase(nif.getName())) {
                    eth0 = nif2String(nif);
                }
                if ("wlan0".equalsIgnoreCase(nif.getName())) {
                    wlan0 = nif2String(nif);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        String address = TextUtils.isEmpty(eth0) ? wlan0 : eth0;
        if (!TextUtils.isEmpty(address)) {
            return address;
        }
        Trace.d("iport", "get SN failed");
        return "";
    }

    /**
     * 获取Installation ID
     *
     * @return
     */
    public static String getInstallationId() {
        return Installation.getID();
    }

    /**
     * 将NetworkInterface信息转换成String
     *
     * @param nif
     * @return
     * @throws SocketException
     */
    private static String nif2String(NetworkInterface nif) throws SocketException {
        byte[] macBytes = nif.getHardwareAddress();
        if (macBytes == null) {
            return null;
        }

        StringBuilder res1 = new StringBuilder();
        for (byte b : macBytes) {
            res1.append(String.format("%02X:", b));
        }

        if (res1.length() > 0) {
            res1.deleteCharAt(res1.length() - 1);
        }
        return res1.toString();
    }

    public static boolean isScreenOn(Context context) {
        try {
            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            if (null == pm) {
                return false;
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
                return pm.isInteractive();
            } else {
                return pm.isScreenOn();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
